package com.house365.core.image;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.widget.ImageView;

/***
 * ͼƬ������
 * 
 */
public class ImageUtil {
	private static final int OPTIONS_NONE = 0x0;
	private static final int OPTIONS_SCALE_UP = 0x1;
	public static final int OPTIONS_RECYCLE_INPUT = 0x2;

	/***
	 * ͨ��url��ȡͼƬbitmap
	 * 
	 * @param picUrl
	 * @return
	 */
	public static Bitmap getBitmapbyUrl(String picUrl) {
		URL url = null;
		URLConnection conn = null;
		InputStream in = null;
		Bitmap itemBitmap = null;
		try {
			url = new URL(picUrl);
			conn = url.openConnection();
			conn.setConnectTimeout(3 * 1000);
			conn.connect();
			in = conn.getInputStream();
			itemBitmap = BitmapFactory.decodeStream(in);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (url != null) {
				url = null;
			}
			if (conn != null) {
				conn = null;
			}
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return itemBitmap;
	}

	/***
	 * ����ͼƬ
	 * 
	 * @param bm
	 * @param fileName
	 * @param quality
	 * @throws IOException
	 */
	public static String saveImage(Bitmap bm, String file, int quality)
			throws IOException {
		if (bm != null) {
			File myCaptureFile = new File(file);
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream(myCaptureFile));
			bm.compress(Bitmap.CompressFormat.JPEG, quality, bos);
			bos.flush();
			bos.close();
		}
		return file;
	}

	/**
	 * ͨ��url��ȡbitmap
	 * 
	 * @param url
	 * @return
	 */
	public static Bitmap returnBitMap(String url) {
		URL myFileUrl = null;
		Bitmap bitmap = null;
		try {
			myFileUrl = new URL(url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		try {
			HttpURLConnection conn = (HttpURLConnection) myFileUrl
					.openConnection();
			conn.setDoInput(true);
			conn.connect();
			InputStream is = conn.getInputStream();
			bitmap = BitmapFactory.decodeStream(is);
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (bitmap != null) {
			return getRoundedCornerBitmap(bitmap);
		}
		return null;
	}

	/**
	 * ��bitmap���Բ��
	 * 
	 * @param bitmap
	 * @return
	 */
	public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
				bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);
		final float roundPx = 8;

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}
	public static Bitmap getRoundedCornerBitmap(Bitmap bitmap,float percentoflen) {
		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
				bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);
		//抗锯齿
//		canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));
		paint.setAntiAlias(true);
//		paint.setFilterBitmap(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		//canvas.drawRoundRect(rectF, bitmap.getWidth()*percentoflen, bitmap.getHeight()*percentoflen, paint);
		canvas.drawRoundRect(rectF, bitmap.getWidth()*percentoflen, bitmap.getHeight()*percentoflen, paint);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}
	/**
	 * ����͸����
	 * 
	 * @param sourceImg
	 * @param number
	 * @return
	 */
	public static Bitmap setAlpha(Bitmap sourceImg, int number) {
		int[] argb = new int[sourceImg.getWidth() * sourceImg.getHeight()];
		sourceImg.getPixels(argb, 0, sourceImg.getWidth(), 0, 0,
				sourceImg.getWidth(), sourceImg.getHeight());// ?��??��???RGB??
		number = number * 255 / 100;
		for (int i = 0; i < argb.length; i++) {
			argb[i] = (number << 24) | (argb[i] & 0x00FFFFFF);// �?????2�????
		}
		sourceImg = Bitmap.createBitmap(argb, sourceImg.getWidth(),
				sourceImg.getHeight(), Config.ARGB_8888);

		return sourceImg;
	}

	/**
	 * �첽��ȡͼƬ
	 * 
	 * @param imageUrl
	 * @param imageView
	 */
	public static void asyncImg(String imageUrl, final ImageView imageView,
			Context context) {
		if (imageUrl == null || imageUrl.equals("")) {
			imageView.setImageBitmap(null);
		} else {
		
			new AsyncImageLoader(context).loadDrawable(imageView,
					imageUrl, new ImageViewLoadListener() {
						public void imageLoaded(Bitmap bitmap, String imageUrl) {
							if (imageView != null) {
								if (bitmap != null) {
									// alphaanimation(imageView, bitmap);
									imageView.setImageBitmap(bitmap);
								}
							}
						}
						@Override
						public void imageLoading() {
							// TODO Auto-generated method stub
							
						}
						@Override
						public void imageLoadedFailure() {
							// TODO Auto-generated method stub
							
						}
					}, AsyncImageLoader.IMAGE_SCALE_TYPE_NONE);
		}

	}

	/**
	 * ��ʾͼƬ͸������
	 * 
	 * @param imageView
	 * @param cachedImage
	 */
	public static void showImageWithRounderCorner(ImageView imageView, Bitmap cachedImage) {
		imageView.setImageBitmap(getRoundedCornerBitmap(cachedImage));
		AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f);
		alphaAnimation.setDuration(400);
		alphaAnimation.setInterpolator(new AccelerateInterpolator());
		imageView.startAnimation(alphaAnimation);
	}
	public static void showImage(ImageView imageView, Bitmap cachedImage,long duration) {
		imageView.setImageBitmap(cachedImage);
		if(duration>0){
			AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f);
			alphaAnimation.setInterpolator(new AccelerateInterpolator());
			alphaAnimation.setDuration(400);
			imageView.startAnimation(alphaAnimation);
		}
	}
	/**
	 * �������ͼ
	 * 
	 * @param source
	 * @param width
	 * @param height
	 * @return
	 */
	public static Bitmap extractThumbImg(Bitmap source, int width, int height) {
		return extractThumbImg(source, width, height, OPTIONS_NONE);
	}

	/***
	 * �������ͼ
	 * 
	 * @param source
	 * @param width
	 * @param height
	 * @param options
	 * @return
	 */
	public static Bitmap extractThumbImg(Bitmap source, int width, int height,
			int options) {
		if (source == null) {
			return null;
		}

		float scale;
		if (source.getWidth() < source.getHeight()) {
			scale = width / (float) source.getWidth();
		} else {
			scale = height / (float) source.getHeight();
		}
		Matrix matrix = new Matrix();
		matrix.setScale(scale, scale);
		Bitmap thumbnail = transform(matrix, source, width, height,
				OPTIONS_SCALE_UP | options);
		return thumbnail;
	}

	private static Bitmap transform(Matrix scaler, Bitmap source,
			int targetWidth, int targetHeight, int options) {
		boolean scaleUp = (options & OPTIONS_SCALE_UP) != 0;
		boolean recycle = (options & OPTIONS_RECYCLE_INPUT) != 0;

		int deltaX = source.getWidth() - targetWidth;
		int deltaY = source.getHeight() - targetHeight;
		if (!scaleUp && (deltaX < 0 || deltaY < 0)) {
			/*
			 * In this case the bitmap is smaller, at least in one dimension,
			 * than the target. Transform it by placing as much of the image as
			 * possible into the target and leaving the top/bottom or left/right
			 * (or both) black.
			 */
			Bitmap b2 = Bitmap.createBitmap(targetWidth, targetHeight,
					Bitmap.Config.ARGB_8888);
			Canvas c = new Canvas(b2);

			int deltaXHalf = Math.max(0, deltaX / 2);
			int deltaYHalf = Math.max(0, deltaY / 2);
			Rect src = new Rect(deltaXHalf, deltaYHalf, deltaXHalf
					+ Math.min(targetWidth, source.getWidth()), deltaYHalf
					+ Math.min(targetHeight, source.getHeight()));
			int dstX = (targetWidth - src.width()) / 2;
			int dstY = (targetHeight - src.height()) / 2;
			Rect dst = new Rect(dstX, dstY, targetWidth - dstX, targetHeight
					- dstY);
			c.drawBitmap(source, src, dst, null);
			if (recycle) {
				source.recycle();
			}
			return b2;
		}
		float bitmapWidthF = source.getWidth();
		float bitmapHeightF = source.getHeight();

		float bitmapAspect = bitmapWidthF / bitmapHeightF;
		float viewAspect = (float) targetWidth / targetHeight;

		if (bitmapAspect > viewAspect) {
			float scale = targetHeight / bitmapHeightF;
			if (scale < .9F || scale > 1F) {
				scaler.setScale(scale, scale);
			} else {
				scaler = null;
			}
		} else {
			float scale = targetWidth / bitmapWidthF;
			if (scale < .9F || scale > 1F) {
				scaler.setScale(scale, scale);
			} else {
				scaler = null;
			}
		}

		Bitmap b1;
		if (scaler != null) {
			b1 = Bitmap.createBitmap(source, 0, 0, source.getWidth(),
					source.getHeight(), scaler, true);
		} else {
			b1 = source;
		}

		if (recycle && b1 != source) {
			source.recycle();
		}

		int dx1 = Math.max(0, b1.getWidth() - targetWidth);
		int dy1 = Math.max(0, b1.getHeight() - targetHeight);

		Bitmap b2 = Bitmap.createBitmap(b1, dx1 / 2, dy1 / 2, targetWidth,
				targetHeight);

		if (b2 != b1) {
			if (recycle || b1 != source) {
				b1.recycle();
			}
		}

		return b2;
	}

	/**
	 * ��ӵ�Ӱ��ԭ�?�ȷ�תͼƬ�����ϵ��·Ŵ�͸����
	 * 
	 * @param originalImage
	 * @return
	 */
	public static Bitmap createReflectedImage(Bitmap originalImage) {
		try {
			// The gap we want between the reflection and the original image
			final int reflectionGap = 4;

			int width = originalImage.getWidth();
			int height = originalImage.getHeight();

			// This will not scale but will flip on the Y axis
			Matrix matrix = new Matrix();
			matrix.preScale(1, -1);

			// Create a Bitmap with the flip matrix applied to it.
			// We only want the bottom half of the image
			Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
					height / 2, width, height / 2, matrix, false);

			// Create a new bitmap with same width but taller to fit reflection
			Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
					(height + height / 2), Config.ARGB_8888);

			// Create a new Canvas with the bitmap that's big enough for
			// the image plus gap plus reflection
			Canvas canvas = new Canvas(bitmapWithReflection);
			// Draw in the original image
			canvas.drawBitmap(originalImage, 0, 0, null);
			// Draw in the gap
			Paint defaultPaint = new Paint();
			canvas.drawRect(0, height, width, height + reflectionGap,
					defaultPaint);
			// Draw in the reflection
			canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

			// Create a shader that is a linear gradient that covers the
			// reflection
			Paint paint = new Paint();
			LinearGradient shader = new LinearGradient(0,
					originalImage.getHeight(), 0,
					bitmapWithReflection.getHeight() + reflectionGap,
					0x70ffffff, 0x00ffffff, TileMode.CLAMP);
			// Set the paint to use this shader (linear gradient)
			paint.setShader(shader);
			// Set the Transfer mode to be porter duff and destination in
			paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
			// Draw a rectangle using the paint with our linear gradient
			canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
					+ reflectionGap, paint);
			return bitmapWithReflection;
		} catch (OutOfMemoryError e) {
			e.printStackTrace();
			System.gc();
		}
		return null;
	}

	// drawable ����ת��Ϊbitmap
	public static Bitmap drawableConverBitmap(Drawable drawable) {

		Bitmap bitmap = Bitmap
				.createBitmap(
						drawable.getIntrinsicWidth(),
						drawable.getIntrinsicHeight(),
						drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
								: Bitmap.Config.RGB_565);
		Canvas canvas = new Canvas(bitmap);
		// canvas.setBitmap(bitmap);
		drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
				drawable.getIntrinsicHeight());
		drawable.draw(canvas);
		return bitmap;
	}

	public static Bitmap getBitMapFromFile(String file) {
		try {
			return BitmapFactory.decodeFile(file);
		} catch (OutOfMemoryError e) {
			return null;
		}
	}

	/**
	 * Bitmapת��Ϊbyte����
	 * 
	 * @param b
	 * @return
	 */
	public static byte[] bitmapToByte(Bitmap b) {
		if (b == null) {
			return null;
		}

		ByteArrayOutputStream o = new ByteArrayOutputStream();
		b.compress(Bitmap.CompressFormat.PNG, 100, o);
		return o.toByteArray();
	}
 

	/**
	 * Drawableת��ΪBitmap
	 * 
	 * @param d
	 * @return
	 */
	public static Bitmap drawableToBitmap(Drawable d) {
		return d == null ? null : ((BitmapDrawable) d).getBitmap();
	}

	/**
	 * Bitmapת��ΪDrawable
	 * 
	 * @param b
	 * @return
	 */
	public static Drawable bitmapToDrawable(Bitmap b) {
		return b == null ? null : new BitmapDrawable(b);
	}

	/**
	 * Drawableת��Ϊbyte����
	 * 
	 * @param d
	 * @return
	 */
	public static byte[] drawableToByte(Drawable d) {
		return bitmapToByte(drawableToBitmap(d));
	}


	/**
	 * ���imageUrl���InputStream����Ҫ�Լ��ֶ��ر�InputStream
	 * 
	 * @param imageUrl
	 *            ͼƬurl
	 * @return
	 */
	public static InputStream getInputStreamFromUrl(String imageUrl) {
		InputStream stream = null;
		try {
			URL url = new URL(imageUrl);
			stream = (InputStream) url.getContent();
		} catch (MalformedURLException e) {
			closeInputStream(stream);
			throw new RuntimeException("MalformedURLException occurred. ", e);
		} catch (IOException e) {
			closeInputStream(stream);
			throw new RuntimeException("IOException occurred. ", e);
		}
		return stream;
	}

	/**
	 * ���imageUrl���Drawable
	 * 
	 * @param imageUrl
	 *            ͼƬurl
	 * @return
	 */
	public static Drawable getDrawableFromUrl(String imageUrl) {
		InputStream stream = getInputStreamFromUrl(imageUrl);
		Drawable d = Drawable.createFromStream(stream, "src");
		closeInputStream(stream);
		return d;
	}

	/**
	 * ���imageUrl���Bitmap
	 * 
	 * @param imageUrl
	 *            ͼƬurl
	 * @return
	 */
	public static Bitmap getBitmapFromUrl(String imageUrl) {
		InputStream stream = getInputStreamFromUrl(imageUrl);
		Bitmap b = BitmapFactory.decodeStream(stream);
		closeInputStream(stream);
		return b;
	}

	/**
	 * �ر�InputStream
	 * 
	 * @param s
	 */
	private static void closeInputStream(InputStream s) {
		if (s != null) {
			try {
				s.close();
			} catch (IOException e) {
				throw new RuntimeException("IOException occurred. ", e);
			}
		}
	}
	/**
	 * sacle the bitmap
	 * @param bitmap
	 * @param sacle
	 * @return
	 */
	public static Bitmap sacleBitmap(Bitmap bitmap,float sacle) {
		  Matrix matrix = new Matrix(); 
		  matrix.postScale(sacle,sacle); //长和宽放大缩小的比例
		  Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
		  return resizeBmp;
	}
	
	public static Bitmap getResizeBitmap(String path, int maxSize) {
		Bitmap bitmap = BitmapFactory.decodeFile(path);
		if (null == bitmap) {
			return null;
		}
		
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
			int options = 100;
			while (baos.toByteArray().length / 1024 > maxSize) {
				options = Math.max(0, options / 2);
				if(options <= 0) {
					break;
				}
				baos.close();
				baos = null;
				baos = new ByteArrayOutputStream();

				bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (OutOfMemoryError e) {
			System.gc();
			System.runFinalization();
		}
		
		return bitmap;
	}
	
	
	/**
	 * 读取图片属性：旋转的角度
	 * @param path 图片绝对路径
	 * @return degree旋转的角度
	 */
    public static int readPictureDegree(String path) {
        int degree  = 0;
        try {
                ExifInterface exifInterface = new ExifInterface(path);
                int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                        degree = 90;
                        break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                        degree = 180;
                        break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                        degree = 270;
                        break;
                }
        } catch (IOException e) {
                e.printStackTrace();
        }
        return degree;
    }
   /*
    * 旋转图片 
    * @param angle 
    * @param bitmap 
    * @return Bitmap 
    */  
   public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {  
       //旋转图片 动作   
       Matrix matrix = new Matrix();;  
       matrix.postRotate(angle);  
       System.out.println("angle2=" + angle);  
       // 创建新的图片   
       Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,  
               bitmap.getWidth(), bitmap.getHeight(), matrix, true);  
       return resizedBitmap;  
   }

}
